﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using FirebirdSql.Data.FirebirdClient;

namespace Model
{
    public class Column
    {
        #region variant
        private int id = -1;
        public int ID
        {
            get { return this.id; }
            set { this.id = value; }
        }

        private int position = int.MaxValue;
        public int Position
        {
            get { return this.position; }
            set { this.position = value; }
        }

        private string name = null;
        public string Name
        {
            get { return this.name; }
            set { this.name = value; }
        }

        private string realName = null;
        public string RealName
        {
            get { return this.realName; }
            set { this.realName = value; }
        }

        private bool pk = false;
        public bool PK
        {
            get { return this.pk; }
            set { this.pk = value; }
        }

        private string dataType = "int";
        public string DataType
        {
            get { return this.dataType; }
            set
            {
                if (value != null)
                    this.dataType = value.Replace(" ", "");
                else
                    this.dataType = value;
            }
        }

        private string fbDataType = "Integer";
        public string FbDataType
        {
            get { return this.fbDataType; }
            set { this.fbDataType = value; }
        }

        private string csharpDataType = "int";
        public string CSharpDataType
        {
            get { return this.csharpDataType; }
            set
            {
                if (value != null)
                    this.csharpDataType = value.Replace(" ", "");
                else
                    this.csharpDataType = value;
            }
        }

        private string csharpNullDataType = "int?";
        public string CSharpNullDataType
        {
            get { return this.csharpNullDataType; }
            set
            {
                if (value != null)
                    this.csharpNullDataType = value.Replace(" ", "");
                else
                    this.csharpNullDataType = value;
            }
        }

        private bool allowNull = true;
        public bool AllowNull
        {
            get { return this.allowNull; }
            set { this.allowNull = value; }
        }

        private string description = null;
        public string Description
        {
            get { return this.description; }
            set
            {
                if (value != null)
                    this.description = value.Replace(" ", "");
                else
                    this.description = value;
            }
        }

        private bool deleted = false;
        public bool Deleted
        {
            get { return this.deleted; }
            set { this.deleted = value; }
        }

        private string csharpDefalutValue = "null";
        public string CSharpDefalutValue
        {
            get { return this.csharpDefalutValue; }
            set { this.csharpDefalutValue = value; }
        }
        #endregion variant


        public Column()
        {
        }

        public Column(FbDataReader readerTable)
        {
            this.id = Convert.ToInt32(readerTable["ID"]);
            this.realName = ((string)readerTable["COLNAME"]).Trim();
            this.position = Convert.ToInt32(readerTable["POS"]);

            if (!(readerTable["ISNULL"] is DBNull))
                this.allowNull = (Convert.ToInt32(readerTable["ISNULL"]) != 1);
            else
                this.allowNull = true;

            switch (Convert.ToInt32(readerTable["DATATYPE"]))
            {
                case 8:
                    this.dataType = "int";
                    this.csharpDataType = "int";
                    this.csharpNullDataType = "int?";
                    this.fbDataType = "Integer";
                    break;
                case 37:
                    this.dataType = "nvarchar(" + readerTable["LEN"].ToString() + ")";
                    this.csharpDataType = "string";
                    this.csharpNullDataType = "string";
                    this.fbDataType = "VarChar";
                    break;
                case 7:
                    this.dataType = "short";
                    this.csharpDataType = "short";
                    this.csharpNullDataType = "short?";
                    this.fbDataType = "SmallInt";
                    break;
                case 14:
                    this.dataType = "bit";
                    this.csharpDataType = "bool";
                    this.csharpNullDataType = "bool?";
                    this.fbDataType = "Char";
                    break;
                case 16:
                    this.dataType = "long";
                    this.csharpDataType = "long";
                    this.csharpNullDataType = "long?";
                    this.fbDataType = "BigInt";
                    break;
                case 10:
                    this.dataType = "float";
                    this.csharpDataType = "double";
                    this.csharpNullDataType = "double?";
                    this.fbDataType = "Float";
                    break;
                case 35:
                    this.dataType = "datetime";
                    this.csharpDataType = "DateTime";
                    this.csharpNullDataType = "DateTime?";
                    this.fbDataType = "TimeStamp";
                    break;
                case 261:
                    this.dataType = "image";
                    this.csharpDataType = "byte[]";
                    this.csharpNullDataType = "byte[]";
                    this.fbDataType = "Binary";

                    if (!(readerTable["ISCHAR"] is DBNull))
                        if (readerTable["ISCHAR"] != null)
                            if (Convert.ToInt32(readerTable["ISCHAR"]) == 0)
                            {
                                this.dataType = "text";
                                this.csharpDataType = "string";
                                this.csharpNullDataType = "string";
                                this.fbDataType = "Text";
                            }
                    break;
            }


            string stmp = "";
            if (!(readerTable["DESCRIP"] is DBNull))
                stmp = ((string)readerTable["DESCRIP"]).Trim();

            this.name = "";
            this.description = "";
            int length = stmp.Length;
            int i = 0;
            int i1 = -1;
            int i2 = -1;

            for (i = 0; i < length; i++)
            {
                if (stmp[i] == '{')
                    i1 = i;
                else
                    if (stmp[i] == '}')
                    {
                        i2 = i;
                        break;
                    }
            }

            if (i2 > i1)
            {
                this.name = stmp.Substring(i1 + 1, i2 - i1 - 1);
                this.description = stmp.Substring(0, i1);
                if (i2 < length - 1)
                    this.description += stmp.Substring(i2 + 1);
            }
            else
                this.description = stmp;

            if (this.name == "")
                this.name = this.realName;
            if (this.description == "")
                this.description = null;

            if (string.IsNullOrEmpty(this.description))
                this.csharpDefalutValue = "null";
            else
            {
                length = this.description.Length;
                i1 = -1;
                i2 = -1;

                for (i = 0; i < length; i++)
                {
                    if (this.description[i] == '[')
                        i1 = i;
                    else
                        if (this.description[i] == ']')
                        {
                            i2 = i;
                            break;
                        }
                }

                if (i2 > i1)
                    this.csharpDefalutValue = description.Substring(i1 + 1, i2 - i1 - 1);
                else
                    this.description = "null";
            }
        }


        #region function
        public Column Clone()
        {
            Column cl = new Column();
            cl.ID = this.id;
            cl.Position = this.position;
            cl.Name = this.name;
            cl.RealName = this.realName;
            cl.PK = this.pk;
            cl.DataType = this.dataType;
            cl.FbDataType = this.fbDataType;
            cl.CSharpDataType = this.csharpDataType;
            cl.CSharpNullDataType = this.csharpNullDataType;
            cl.AllowNull = this.allowNull;
            cl.Description = this.description;
            cl.Deleted = this.deleted;
            cl.CSharpDefalutValue = this.csharpDefalutValue;

            return cl;
        }

        public string GetFireBirdDataType()
        {
            string _dataType = this.dataType.ToUpper();
            if (_dataType.StartsWith("NVARCHAR("))
                _dataType = _dataType.Replace("NVARCHAR(", "Varchar(") + " CHARACTER SET UTF8";
            else
            {
                switch (_dataType)
                {
                    case "BIT":
                        _dataType = "Char(1)";
                        break;
                    case "BINARY":
                        _dataType = "Blob";
                        break;
                    case "DATETIME":
                        _dataType = "TimeStamp";
                        break;
                    case "FLOAT":
                        _dataType = "Float";
                        break;
                    case "INT":
                        _dataType = "Integer";
                        break;
                    case "IMAGE":
                        _dataType = "Blob Sub_type BINARY";
                        break;
                    case "LONG":
                        _dataType = "Bigint";
                        break;
                    case "SHORT":
                        _dataType = "Smallint";
                        break;
                    case "TEXT":
                        _dataType = "Blob Sub_type TEXT";
                        break;
                }
            }

            return _dataType;
        }

        public string GetColumnSQL()
        {
            string _dataType = GetFireBirdDataType();

            string s = this.realName + " " + _dataType;
            if (allowNull == false)
                s += " NOT NULL";

            return s;
        }
        #endregion function
    }
}
